package com.xup.luckymoney.job;

import android.annotation.TargetApi;
import android.content.res.Resources;
import android.os.Build;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.xup.luckymoney.Config;
import com.xup.luckymoney.LuckyMoneyService;
import com.xup.luckymoney.R;

import java.util.List;
public class WechatAccessibilityJob extends BaseAccessibilityJob {

    private static final String TAG = "WechatAccessibilityJob";
    private static final boolean DEBUG = true;

    private static final String TALK_LIST_LAUNCHER_UI = "com.tencent.mm.ui.LauncherUI";
    private static final String LUCKY_MONEY_RECEIVE_UI =
            "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyReceiveUI";
    private static final String LUCKY_MONEY_DETAIL_UI =
            "com.tencent.mm.plugin.luckymoney.ui.LuckyMoneyDetailUI";

    private String wechatHongbao, stringOpenHongBao, haveSendAhongbao, lookOthersLuck;

    /**
     * wechat version 6.3.9
     */
    private static final int WECHAT_VERSION_700 = 700;
    private static final String WECHAT_LUCKYMONEY_OPEN_V700 = "com.tencent.mm:id/b2c";
    /**
     * wechat version 6.3.16
     */
    private static final int WECHAT_VERSION_740 = 740;
    private static final String WECHAT_LUCKYMONEY_OPEN_V740 = "com.tencent.mm:id/b43";
    /**
     * wechat version 6.3.15
     */
    private static final int WECHAT_VERSION_760 = 760;
    private static final String WECHAT_LUCKYMONEY_OPEN_V760 = "com.tencent.mm:id/b3h";

    private static final int WECHAT_VERSION_800 = 800;
    private static final String WECHAT_LUCKYMONEY_OPEN_V800 = "com.tencent.mm:id/b9m";

    private AccessibilityNodeInfo targetNode = null;

    @Override
    public void onCreateJob(LuckyMoneyService service) {
        super.onCreateJob(service);

        service.updateWechatPackageInfo();

        Resources res = getContext().getResources();
        wechatHongbao = res.getString(R.string.weixin_hongbao);
        stringOpenHongBao = res.getString(R.string.open_hongbao);
        haveSendAhongbao = res.getString(R.string.have_send_one_hongbao);
        lookOthersLuck = res.getString(R.string.look_others_luck);
    }

    @Override
    public void onStopJob() {
        super.onStopJob();
    }

    @Override
    public boolean isEnable() {
        return getConfig().getWehcatEnable();
    }

    @Override
    public String getTargetPackageName() {
        return Config.WECHAT_PACKAGENAME;
    }

    @Override
    public void onReceiveJob(AccessibilityEvent event) {
        final int eventType = event.getEventType();

        if (DEBUG) Log.d(TAG, "onReceiveJob, AccessibilityEvent--->" + event);
        if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
            List<CharSequence> texts = event.getText();
            if (!texts.isEmpty()) {
                for (CharSequence t : texts) {
                    String text = String.valueOf(t);
                    if (DEBUG) Log.d(TAG, "event text = " + text);
                    if (text.contains(wechatHongbao)) {
                        openNotify(event);
                        break;
                    }
                }
            }
        } else if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            if (isGrabEnd()) {
                if (DEBUG) Log.i(TAG, "not allowed to do node sniff");
                return;
            }
            openHongBao(event);
        } else if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
            if (isGrabEnd()) {
                if (DEBUG) Log.i(TAG, "not allowed to do node sniff");
                return;
            }
            // the TYPE_WINDOW_CONTENT_CHANGED not used now
            if ("android.widget.ListView".equals(event.getClassName())) {
                // go to wechat communicate interface
                handleChatListHongBao();
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void openHongBao(AccessibilityEvent event) {
        if (LUCKY_MONEY_RECEIVE_UI.equals(event.getClassName())) {
            if (isEnable()) {
                if (DEBUG) Log.d(TAG, "open red packet.");
                clickOpenOfRedPacket();
                getHongbaoEnd();
            } else {
                Log.i(TAG, "wechat red packet auto grab is disabled");
                getHongbaoEnd();
            }
        } else if (LUCKY_MONEY_DETAIL_UI.equals(event.getClassName())) {
            // after open, we can only see the detail record
            // but do nothing now
        } else if (TALK_LIST_LAUNCHER_UI.equals(event.getClassName())) {
            // after open wechat, open red packet
            handleChatListHongBao();
        }
    }

    /**
     * click open button to open red packet
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void clickOpenOfRedPacket() {
        AccessibilityNodeInfo nodeInfo = getService().getRootInActiveWindow();
        if (nodeInfo == null) {
            if (DEBUG) Log.e(TAG, "rootWindow is null");
            return;
        }

        List<AccessibilityNodeInfo> list = null;
        int event = getConfig().getWechatAfterOpenHongBaoEvent();
        if (event == Config.EVENT_OPEN) {
            String openButtonId = getWechatBtId();
            if (getService().getWechatVersion() < WECHAT_VERSION_700) {
                list = nodeInfo.findAccessibilityNodeInfosByText(stringOpenHongBao);
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
                        && openButtonId != null) {
                    list = nodeInfo.findAccessibilityNodeInfosByViewId(openButtonId);
                }
                if (list == null || list.isEmpty()) {
                    if (DEBUG) Log.w(TAG, "list is null or empty, the button id is error");
                    findOpenButton(nodeInfo);
                }
            }
        } else if (event == Config.EVENT_OBSERVE) {
            // only in low version, look others luck
            if (getService().getWechatVersion() < WECHAT_VERSION_700) {
                list = nodeInfo.findAccessibilityNodeInfosByText(lookOthersLuck);
            }
        }

        if (list != null && !list.isEmpty()) {
            targetNode = list.get(0);
        }

        if (targetNode != null) {
            final AccessibilityNodeInfo n = targetNode;
            targetNode = null;
            long sDelayTime = getConfig().getWechatOpenDelayTime();
            if (sDelayTime != 0) {
                getHandler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        findClickableParent(n);
                    }
                }, sDelayTime);
            } else {
                findClickableParent(n);
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void handleChatListHongBao() {
        AccessibilityNodeInfo nodeInfo = getService().getRootInActiveWindow();
        if (nodeInfo == null) {
            if (DEBUG) Log.w(TAG, "rootWindow is null");
            return;
        }

        List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText(getHongbao);
        if (list == null || list.isEmpty()) {
            // find hongbao from the chat list
            if (DEBUG) Log.i(TAG, "try use " + wechatHongbao + "to find node info");
            list = nodeInfo.findAccessibilityNodeInfosByText(wechatHongbao);

            if (list == null || list.isEmpty()) {
                Log.e(TAG, "can not find wechat red packet");
                return;
            }
        }
        // get hongbao from the latest
        for (int i = list.size() - 1; i >= 0; i--) {
            AccessibilityNodeInfo parent = list.get(i);
            if (DEBUG) Log.i(TAG, "-->handleChatListHongBao():" + parent);
            if (parent != null) {
                if (!isGrabEnd()) {
                    findClickableParent(parent);
                }
                break;
            }
        }
    }

    private void findOpenButton(AccessibilityNodeInfo info) {
        int childCount = info.getChildCount();
        if (childCount == 0) {
            if (DEBUG) Log.d(TAG, "ClassName:" + info.getClassName() + ", text : " + info.getText());
            Log.d(TAG, "findOpenButton, info: " + info);
            if (clickToOpen.equals(info.getText())) {
                targetNode = info;
            }
            if (targetNode == null && "android.widget.Button".equals(info.getClassName())) {
                targetNode = info;
            }
        } else {
            for (int i = 0; i < childCount; i++) {
                if (info.getChild(i) != null) {
                    findOpenButton(info.getChild(i));
                }
            }
        }
        if (targetNode == null) {
            Log.e(TAG, "findOpenButton(), can not find the open button");
            // showToast(R.string.can_not_find_wechat_open_button);
        }
    }

    private String getWechatBtId() {
        String wechatBtId = "";
        int version = getService().getWechatVersion();
        switch (version) {
            case WECHAT_VERSION_700:
                wechatBtId = WECHAT_LUCKYMONEY_OPEN_V700;
                break;
            case WECHAT_VERSION_740:
                wechatBtId = WECHAT_LUCKYMONEY_OPEN_V740;
                break;
            case WECHAT_VERSION_760:
                wechatBtId = WECHAT_LUCKYMONEY_OPEN_V760;
                break;
            case WECHAT_VERSION_800:
                wechatBtId =  WECHAT_LUCKYMONEY_OPEN_V800;
                break;
            default:
                Log.w(TAG, "wechat version is: " + version + ", app need update!");
                break;
        }
        return wechatBtId;
    }
}
